/**
  ******************************************************************************
  * @file    poolmanage.c
  * @author  Dragon.Chen
  * @version V1.0.2
  * @date    11-26-2014
  * @brief   内存管理
  ******************************************************************************
  *
  * <h2><center>&copy; COPYRIGHT 2014 上海今中网络科技有限公司 </center></h2>
  ******************************************************************************
  */

#include "pool.h"

/*********************************** sock_buffer *******************************
 * 管理sock_buffer数据结构:
 *
 * NAME: SOCK_BUFFER_MANAGE_T   |<------------------- nSockBufferList ----------------->|
 * +--------------------+       NAME: SOCK_BUFFER_LIST_T    NAME: SOCK_BUFFER_LIST_T
 * | sockBufferListHead +------>+-----------------+         +-----------------+
 * | nSockBufferList    | +-----| sockBufferhead  | +-------| sockBufferhead  |
 * | maxSockBufferList  | | +---| freeSockBuffer  | +-------| freeSockBuffer  |     ......
 * | nSockBuffer        | | |   | nUsedSockBuffer | |       | nUsedSockBuffer |
 * +--------------------+ | |   | next            +-|------>+ next            +---->
 *                        | |   +-----------------+ |       +-----------------+
 *                        | |                       |
 *                        | |   NAME:SOCK_BUFFER_T  |       NAME:SOCK_BUFFER_T
 *              -+-       +-|-->+----------------+  +------>+----------------+      ......
 *               |          |   | buffer         |          | buffer         |
 *               |          |   | bufferLength   |          | bufferLength   |
 *               |          |   | bufferPosition |          | bufferPosition |
 *               |          |   | data           +--+       | data           +--+
 *               |          +-->+----------------+<-+       +----------------+<-+
 *               |              | buffer         |          | buffer         |
 *           nSockBuffer        | bufferLength   |          | bufferLength   |
 *               |              | bufferPosition |          | bufferPosition |
 *               |              | data           +--+       | data           +--+
 *               |              +----------------+<-+       +----------------+<-+
 *               |              | buffer         ||         | buffer         |
 *               |              | bufferLength   ||         | bufferLength   |
 *               |              | bufferPosition ||         | bufferPosition |
 *               |              | data           +--+       | data           +--+
 *               |              +----------------+<-+       +----------------+<-+
 *              -+-             ......                      ......
 *
 ******************************************************************************/

/**
  * @brief  申请sockBuffer
  * @param  NULL
  * @retval void
  */
#define get_sock_buffer_list()  (SOCK_BUFFER_LIST_T *)calloc(1, sizeof(SOCK_BUFFER_LIST_T))

/**
  * @brief  尾部插入
  * @param  arg1:head  arg2:待插入sockBufferList
  * @retval void
  */
static void insert_sock_buffer_list(SOCK_BUFFER_LIST_T *head, SOCK_BUFFER_LIST_T *newNode)
{
    SOCK_BUFFER_LIST_T *currNode = head;
    while (currNode->next != NULL)
        currNode = currNode->next;
    currNode->next = newNode;
}

/**
  * @brief  释放sockBufferList
  * @param  arg1:head  arg2:待释放sockBufferList
  * @retval void
  */
static void free_sock_buffer_list(SOCK_BUFFER_LIST_T *head, SOCK_BUFFER_LIST_T *oldNode)
{
    SOCK_BUFFER_LIST_T *prevNode = head;
    SOCK_BUFFER_LIST_T *currNode = head->next;

    while (currNode != NULL)
    {
        if (currNode == oldNode)
        {
            prevNode->next = currNode->next;
            if (currNode->sockBufferhead)
            {
                free(currNode->sockBufferhead);
                currNode->sockBufferhead = NULL;
                currNode->freeSockBuffer = NULL;
                currNode->next = NULL;
            }
            free(currNode);
            break;
        }

        prevNode = currNode;
        currNode = currNode->next;
    }
}

/**
  * @brief  释放所有申请的内存
  * @param  arg1:head
  * @retval void
  */
void finalize_sock_buffer(SOCK_BUFFER_MANAGE_T *sockBufferManage)
{
    SOCK_BUFFER_LIST_T *currNode;
    SOCK_BUFFER_LIST_T *nextNode;
    currNode = sockBufferManage->sockBufferListHead;

    while(currNode != NULL)
    {
        nextNode = currNode->next;
        if (currNode->sockBufferhead)
        {
            free(currNode->sockBufferhead);
            currNode->sockBufferhead = NULL;
            currNode->freeSockBuffer = NULL;
            currNode->next = NULL;
        }
        free(currNode);
        currNode = nextNode;
    }
}

/**
  * @brief  回收sockBuffer
  * @param  arg1:sockBufferManage  arg2:待释放的sockBuffer
  * @retval 成功返回获取sockBuffer，失败返回NULL
  */
void free_sock_buffer(SOCK_BUFFER_MANAGE_T *sockBufferManage, SOCK_BUFFER_T *sockBuffer)
{
    SOCK_BUFFER_LIST_T *currSockBufferList;
    SOCK_BUFFER_LIST_T *nextSockBufferList;

    /// 回收sockBuffer
    currSockBufferList = sockBufferManage->sockBufferListHead;
    while (currSockBufferList != NULL)
    {
        if ( (sockBuffer >= currSockBufferList->sockBufferhead) &&
             (sockBuffer < (SOCK_BUFFER_T *)((char *)currSockBufferList->sockBufferhead +
              sizeof(SOCK_BUFFER_T) * sockBufferManage->nSockBuffer)) )
        {
            ZeroMemory(sockBuffer, sizeof(SOCK_BUFFER_T));
            sockBuffer->data = (void *)currSockBufferList->freeSockBuffer;
            currSockBufferList->freeSockBuffer = sockBuffer;
            currSockBufferList->nUsedSockBuffer--;
            break;
        }

        currSockBufferList = currSockBufferList->next;
    }

    /// 当sockBufferList的个数大于maxSockBufferList时，如果有空闲资源就直接释放
    if (sockBufferManage->nSockBufferList > sockBufferManage->maxSockBufferList)
    {
        currSockBufferList = sockBufferManage->sockBufferListHead->next;

        while (currSockBufferList != NULL)
        {
            if (currSockBufferList->nUsedSockBuffer == 0)
            {
                nextSockBufferList = currSockBufferList->next;
                free_sock_buffer_list(sockBufferManage->sockBufferListHead, currSockBufferList);
                sockBufferManage->nSockBufferList--;
                if (sockBufferManage->nSockBufferList <= sockBufferManage->maxSockBufferList)
                    break;
                currSockBufferList = nextSockBufferList;
                continue;
            }

            currSockBufferList = currSockBufferList->next;
        }
    }
}

/**
  * @brief  获取sockBuffer
  * @param  arg1:sockBufferManage
  * @retval 成功返回获取sockBuffer，失败返回NULL
  * @attention 请勿必重复申请，init_sock_buffer和free_sock_buffer必须成对使用，用完一定要释放
  */
SOCK_BUFFER_T *get_sock_buffer(SOCK_BUFFER_MANAGE_T *sockBufferManage)
{
    int                  i;
    SOCK_BUFFER_T       *tempSockBuffer;
    SOCK_BUFFER_LIST_T  *tempSockBufferList;

    /// 遍历sockBufferList查找空闲的sockBuffer
    tempSockBufferList = sockBufferManage->sockBufferListHead;
    while (tempSockBufferList != NULL)
    {
        if (tempSockBufferList->freeSockBuffer == NULL)
        {
            tempSockBufferList = tempSockBufferList->next;
            continue;
        }
        else
        {
            tempSockBuffer = tempSockBufferList->freeSockBuffer;
            tempSockBufferList->freeSockBuffer = (SOCK_BUFFER_T *)tempSockBuffer->data;
            tempSockBufferList->nUsedSockBuffer++;
            return tempSockBuffer;
        }
    }

    /// sockBufferList没有空闲的申请新的sockBufferList的元素，并将插入到sockBufferList中，失败返回NULL
    if ((tempSockBufferList = get_sock_buffer_list()) == NULL)
    {
        return NULL;
    }
    insert_sock_buffer_list(sockBufferManage->sockBufferListHead, tempSockBufferList);
    sockBufferManage->nSockBufferList++;

    /// 为sockBufferList中的成员初始化
    tempSockBufferList->sockBufferhead = (SOCK_BUFFER_T *)calloc(sockBufferManage->nSockBuffer, sizeof(SOCK_BUFFER_T));
    if (tempSockBufferList->sockBufferhead == NULL)
    {
        free_sock_buffer_list(sockBufferManage->sockBufferListHead, tempSockBufferList);
        sockBufferManage->nSockBufferList--;
        return NULL;
    }

    tempSockBufferList->freeSockBuffer = tempSockBufferList->sockBufferhead;
    for (i=0; i<sockBufferManage->nSockBuffer-1; i++)
        tempSockBufferList->sockBufferhead[i].data = (void *)&tempSockBufferList->sockBufferhead[i+1];

    /// 从新申请的内存中分配sockBuffer
    tempSockBuffer = tempSockBufferList->freeSockBuffer;
    tempSockBufferList->freeSockBuffer = (SOCK_BUFFER_T *)tempSockBuffer->data;
    tempSockBufferList->nUsedSockBuffer++;
    return tempSockBuffer;
}

/**
  * @brief  初始化数据sock_buffer
  * @param  arg1:sockBufferManage
  * @retval void
  */
void init_sock_buffer(SOCK_BUFFER_MANAGE_T *sockBufferManage)
{
    int                 i;
    SOCK_BUFFER_LIST_T *tempSockBufferList;

    /// 申请sockBufferList头部
    sockBufferManage->sockBufferListHead = get_sock_buffer_list();
    assert_param(sockBufferManage->sockBufferListHead);

    /// 申请指定个数sockBufferList元素
    for (i=1; i<sockBufferManage->nSockBufferList; i++)
    {
        tempSockBufferList = get_sock_buffer_list();
        assert_param(tempSockBufferList);
        insert_sock_buffer_list(sockBufferManage->sockBufferListHead, tempSockBufferList);
    }

    /// 为sockBufferList中每个元素初始化
    tempSockBufferList = sockBufferManage->sockBufferListHead;
    while (tempSockBufferList != NULL)
    {
        tempSockBufferList->sockBufferhead = (SOCK_BUFFER_T *)calloc(sockBufferManage->nSockBuffer, sizeof(SOCK_BUFFER_T));
        assert_param(tempSockBufferList->sockBufferhead != NULL);
        tempSockBufferList->freeSockBuffer = tempSockBufferList->sockBufferhead;
        for (i=0; i<sockBufferManage->nSockBuffer-1; i++)
            tempSockBufferList->sockBufferhead[i].data = (void *)&tempSockBufferList->sockBufferhead[i+1];

        tempSockBufferList = tempSockBufferList->next;
    }
}

/***************************** client data *****************************/
/**
  * @brief  初始化用户数据
  * @param  arg1:clientDataManage
  * @retval void
  */
void init_client_data(CLIENT_DATA_MANAGE_T *clientDataManage)
{
    int i;

    clientDataManage->clientDataHead = (CLIENT_DATA_T *)calloc(clientDataManage->nClientData, sizeof(CLIENT_DATA_T));
    assert_param(clientDataManage->clientDataHead != NULL);
    clientDataManage->freeClientData = clientDataManage->clientDataHead;
    clientDataManage->usedClientData = (CLIENT_DATA_T *)calloc(clientDataManage->nClientData, 1);
    assert_param(clientDataManage->usedClientData != NULL);

    for (i=0; i<clientDataManage->nClientData-1; i++)
        clientDataManage->clientDataHead[i].next = &clientDataManage->clientDataHead[i+1];
}

/**
  * @brief  获取空闲的用户数据
  * @param  arg1:clientDataManage
  * @retval 成功返回tempClientData，失败返回NULL
  */
CLIENT_DATA_T *get_client_data(CLIENT_DATA_MANAGE_T *clientDataManage)
{
    CLIENT_DATA_T *tempClientData;

    if (clientDataManage->freeClientData == NULL)
        return NULL;

    /// 获取空闲的用户数据
    tempClientData = clientDataManage->freeClientData;
    clientDataManage->freeClientData = tempClientData->next;

    /// 加入已经链接链表
    tempClientData->next = clientDataManage->usedClientData->next;
    clientDataManage->usedClientData->next = tempClientData;

    return tempClientData;
}

/**
  * @brief  释放的用户数据
  * @param  arg1:clientDataManage  arg2:clientData
  * @retval void
  */
void free_client_data(CLIENT_DATA_MANAGE_T *clientDataManage, CLIENT_DATA_T *clientData)
{
    CLIENT_DATA_T *currClientData;
    CLIENT_DATA_T *prevClientData;

    if (clientData == NULL)
        return;

    /// 从已经链接链表移除
    prevClientData = clientDataManage->usedClientData;
    currClientData = clientDataManage->usedClientData->next;
    while (currClientData)
    {
        if (currClientData == clientData)
        {
            prevClientData->next = currClientData->next;
            break;
        }
        prevClientData = currClientData;
        currClientData = currClientData->next;
    }

    /// 释放的用户数据
    ZeroMemory(clientData, sizeof(CLIENT_DATA_T));
    clientData->next = clientDataManage->freeClientData;
    clientDataManage->freeClientData = clientData;
}


/**
  * @brief  释放所有的用户数据
  * @param  arg1:clientDataManage  arg2:clientData
  * @retval void
  */
void finalize_client_data(CLIENT_DATA_MANAGE_T *clientDataManage)
{
    free(clientDataManage->clientDataHead);
    clientDataManage->clientDataHead = NULL;
    clientDataManage->freeClientData = NULL;
    clientDataManage->nClientData    = 0;
    clientDataManage->nUsedClientData= 0;
}

/***************************** certificate *****************************/

/**
  * @brief  初始化证书
  * @param  arg1:clientDataManage  arg2:clientData
  * @retval void
  */
void init_certifcate(CERTIFICATE_MANAGE_T *certificateManage)
{
    int i;

    certificateManage->certificateHead = (CERTIFICATE_T *)calloc(certificateManage->nCertificate, sizeof(CERTIFICATE_T));
    assert_param(certificateManage->certificateHead != NULL);
    certificateManage->freeCertificate = certificateManage->certificateHead;

    for (i=0; i<certificateManage->nCertificate-1; i++)
        certificateManage->certificateHead[i].next = &certificateManage->certificateHead[i+1];
}

/**
  * @brief  释放所有的内存
  * @param  arg1:certificateManage
  * @retval void
  */
void finalize_certificate(CERTIFICATE_MANAGE_T *certificateManage)
{
    free(certificateManage->certificateHead);
    certificateManage->certificateHead = NULL;
    certificateManage->freeCertificate = NULL;
    certificateManage->nCertificate    = 0;
}

/******************* (C) COPYRIGHT 2014 上海今中网络科技有限公司 *****END OF FILE****/



